#include <linux/init.h>
#include <linux/module.h>
#include <linux/security.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <linux/sched.h>

MODULE_LICENSE("GPL");

static int __init malloc_test_init(void);
static void __exit malloc_test_exit(void);

#define VMALLOC_user_SIZE 8092

char * addr;

int __init malloc_test_init(void)
{
	addr = (char *)vmalloc_user(VMALLOC_user_SIZE);
	if( addr == NULL )
		printk("vmalloc failed! \n");
	else
	{
		// 输出创建的地址区间的虚拟地址
		printk("vmalloc successfully! addr = %lx\n", (unsigned long)addr);
		printk("*addr = %d\n", *addr);               //地址区间起始位置的内容
		printk("*(addr+50) = %d\n", *(addr+50));     //地址区间偏移为50处的内容
	}

	struct mm_struct *mm = current->mm;                  //mm指向当前进程的地址空间
	unsigned long addra = mm->mmap->vm_start + 1;          //进程虚拟区间中某一地址
	printk("addra=0x%lx\n", addra);
	struct vm_area_struct * vma = find_vma(mm, addra); //找到地址addr所属的线性区间
	
	if(vma != NULL )
	{
		printk("vma->vm_start=0x%lx\n", vma->vm_start);
		printk("vma->vm_end=0x%lx\n", vma->vm_end);
		int page_number = vma_pages(vma);               //获得线性区间vma所包含的页数
		printk("the page_number of vma is:%d\n", page_number);
	}
	else
		printk("You have failed! \n");


	return 0;
}

void __exit malloc_test_exit(void)
{
	if(addr != NULL)
		vfree( addr );
	printk("exit! \n");
}

module_init(malloc_test_init);
module_exit(malloc_test_exit);
